/**
  ******************************************************************************
  * @file    server.ino
  * @version V1.0
  * @date    2022-06-04
  * @author  码农爱学习(xxpcb)
  * @brief   RVB2601综合项目（【平头哥RVB2601创意应用开发】+ 智慧家居助手）
  *          的家居电器控制功能的ESP8266端程序（灯的控制、风扇的控制）
  *
  * @attention 需要按需修改：自己的WIFI名和密码
  * 
  * 本项目视频演示地址：https://www.bilibili.com/video/BV1ZY411T7nb
  * 个人博客:https://xxpcb.gitee.io
  ******************************************************************************
  */
#include <ESP8266WiFi.h>

const char* ssid = "MERCURY_3394"; //<----修改为自己的
const char* password = "xxxxxxxxxxx"; //<----修改为自己的
#define MAX_SRV_CLIENTS 2  //做多多少个客户端可以连接
#define PORT 666

#define LED1_PIN 2
#define LED2_PIN 14
#define FAN_PIN 12

WiFiServer server(PORT);    //创建server,并指定端口号
WiFiClient serverClients[MAX_SRV_CLIENTS];   //定义最多多少个client可以连接本server(一般不要超过4个)

void splitBySpace(String &src, std::vector<String> &dst)
{
  int splitpos = 0;
  String recvStr = src;
  std::vector<String> splitArr;
  do {
    splitpos = recvStr.indexOf(' ');//找到字符串中逗号出现的位置
    if (splitpos != -1) //如果能找到逗号
    {
      //Serial.println(recvStr.substring(0, splitpos)); //打印找到的逗号之前的文本
      splitArr.push_back(recvStr.substring(0, splitpos));
      recvStr = recvStr.substring(splitpos + 1, recvStr.length()); //recvStr变成去掉已打印的文本的剩余文本
    }
    else //如果没有找到逗号
    {
      if (recvStr.length() > 0) //message是否存在文本
      {
        //Serial.println(recvStr);//将改文本串口输出
        splitArr.push_back(recvStr);
      }
    }
  }
  while (splitpos >= 0); //当逗号位置存在
  dst = splitArr;
#if 0 //test
  Serial.println("===========");
  for (int i=0; i<dst.size(); i++)
  {
    Serial.println("-----------");
    Serial.println(dst[i]);
    Serial.println("---");
    Serial.println(dst[i].length());
    Serial.println("---");
    for (int j=0; j<dst[i].length(); j++)
    {
      Serial.println(dst[i][j]);
    }
    Serial.println("-----------");
  }
  Serial.println("===========");
#endif
}

void setup()
{
  //初始化LED
  pinMode(LED1_PIN, OUTPUT);
  digitalWrite(LED1_PIN, HIGH);
  pinMode(LED2_PIN, OUTPUT);
  digitalWrite(LED2_PIN, LOW);

  pinMode(FAN_PIN, OUTPUT);
  digitalWrite(FAN_PIN, LOW);
  
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  delay(500);
  Serial.print("连接到:");
  Serial.println(ssid);
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20)
  {
    delay(500);
  }
  if (i == 21)
  {
    Serial.print("没能连接到:");
    Serial.println(ssid);
    return ;
  }

  server.begin();  //启动server
  server.setNoDelay(true);//关闭小包合并包功能，不会延时发送数据

  Serial.print("准备好了！使用的网络IP是: ");
  Serial.println(WiFi.localIP());
  Serial.print("端口是：");
  Serial.println(PORT);
}

void loop()
{
  uint8_t i;

  if (server.hasClient())
  { //判断是否有新的client请求进来
    for (i = 0; i < MAX_SRV_CLIENTS; i++)
    {
      //释放旧无效或者断开的client
      if (!serverClients[i] || !serverClients[i].connected())
      {
        if (!serverClients[i])
        {
          //serverClients[i]    判断指定序号的客户端是否有效
          serverClients[i].stop();  //停止指定客户端的连接
        }

        serverClients[i] = server.available();//分配最新的client
        Serial.print("1个新的客户端: ");
        Serial.println(i);
        break; //跳出一层for循环
      }
    }

    //当达到最大连接数 无法释放无效的client，需要拒绝连接
    if (i == MAX_SRV_CLIENTS)
    {
      WiFiClient client = server.available();
      client.stop();
      Serial.println("连接被拒绝 ");
    }
  }
  
  //检测client发过来的数据
  for (i = 0; i < MAX_SRV_CLIENTS; i++)
  {
    if (serverClients[i] && serverClients[i].connected())
    {
      if (serverClients[i].available())
      {
        //serverClients[i].available()   判断指定客户端是否有可读数据
        String recvStr = "";
        while (serverClients[i].available())
        {
          recvStr += char(serverClients[i].read());
          //Serial.write(serverClients[i].read());
        }
        Serial.println("收到客户端的信息：");
        Serial.println(recvStr);
        std::vector<String> splitStr;
        splitBySpace(recvStr, splitStr);
        if (splitStr.size() == 2)
        {
          if (splitStr[0] == "led")
          {
            if (splitStr[1] == "on")
            {
              Serial.println("开灯1");
              digitalWrite(LED1_PIN, LOW); // 点亮LED
            }
            else if (splitStr[1] == "off")
            {
              Serial.println("关灯1");
              digitalWrite(LED1_PIN, HIGH); // 熄灭LED
            }
          }
          else if (splitStr[0] == "led2")
          {
            if (splitStr[1] == "on")
            {
              Serial.println("开灯2");
              digitalWrite(LED2_PIN, HIGH); // 点亮LED
            }
            else if (splitStr[1] == "off")
            {
              Serial.println("关灯2");
              digitalWrite(LED2_PIN, LOW); // 熄灭LED
            }
          }
          else if (splitStr[0] == "fan")
          {
            if (splitStr[1] == "on")
            {
              Serial.println("开风扇");
              digitalWrite(FAN_PIN, HIGH); // 开风扇
            }
            else if (splitStr[1] == "off")
            {
              Serial.println("关风扇");
              digitalWrite(FAN_PIN, LOW); // 关风扇
            }
          }
        }
      }
    }
  }
}
